﻿''' <summary>
''' CompareToやCloneが可能なオブジェクトの基底クラス。
''' </summary>
''' <version>1.0 [sonodar] 2011/07/24 新規作成</version>
<Serializable()> _
Public Class BaseObject
    Implements IComparable, IComparable(Of BaseObject), ICloneable

    ''' <summary>
    ''' このインスタンスとobjのキー項目(<see cref="Attribute.KeyAttribute">Key属性</see>が付与されたプロパティ(フィールド))を比較し、<br/>
    ''' すべて一致したらTrueを返す。<br/>
    ''' キー項目が定義されていなければ、すべてのプロパティ(フィールド)を定義順に比較する。<br/>
    ''' 継承関係がなくても、キー項目が一致していれば比較可能。
    ''' </summary>
    ''' <param name="obj">値を比較するオブジェクト</param>
    ''' <returns>キー項目がすべて一致したらTrue</returns>
    Public Overrides Function Equals(ByVal obj As Object) As Boolean
        'FIXME 未実装 Sonodar.Common.BaseObject#Equals(Object)
        Throw New NotImplementedException()
    End Function

    ''' <summary>
    ''' このオブジェクトのハッシュ値を取得する。
    ''' </summary>
    ''' <returns>オブジェクトのハッシュ値</returns>
    Public Overrides Function GetHashCode() As Integer
        'FIXME 未実装 Sonodar.Common.BaseObject#GetHashCode()
        Throw New NotImplementedException()
    End Function

    ''' <summary>
    ''' このインスタンスとotherのキー項目(<see cref="Attribute.KeyAttribute">Key属性</see>が付与されたプロパティ(フィールド))を比較し、<br/>
    ''' 大小比較結果を返す。<br/>
    ''' キー項目が定義されていなければ、すべてのプロパティ(フィールド)を定義順に比較する。<br/>
    ''' 継承関係がなくても、キー項目が一致していれば比較可能。
    ''' </summary>
    ''' <param name="other">値を比較するオブジェクト</param>
    ''' <returns>大小比較結果</returns>
    Public Function CompareTo(ByVal other As Object) As Integer Implements IComparable.CompareTo
        'FIXME 未実装 Sonodar.Common.BaseObject#CompareTo(Object)
        Throw New NotImplementedException()
    End Function

    ''' <summary>
    ''' このインスタンスとotherのキー項目(<see cref="Attribute.KeyAttribute">Key属性</see>が付与されたプロパティ(フィールド))を比較し、<br/>
    ''' 大小比較結果を返す。<br/>
    ''' キー項目が定義されていなければ、すべてのプロパティ(フィールド)を定義順に比較する。<br/>
    ''' 継承関係がなくても、キー項目が一致していれば比較可能。
    ''' </summary>
    ''' <param name="other">値を比較するオブジェクト</param>
    ''' <returns>大小比較結果</returns>
    Public Function CompareTo(ByVal other As BaseObject) As Integer Implements IComparable(Of BaseObject).CompareTo
        'FIXME 未実装 Sonodar.Common.BaseObject#CompareTo(BaseObject)
        Throw New NotImplementedException()
    End Function

#Region "演算子のオーバーロード"

    ''' <summary>
    ''' obj2のプロパティ値(フィールド値)をobj1のプロパティ値(フィールド値)に上書きした<br/>
    ''' オブジェクトの新規インスタンスを返す。<br/>
    ''' 継承関係がなくても、キー項目が一致していれば比較可能。
    ''' </summary>
    ''' <param name="obj1">値が上書きされるオブジェクトのインスタンス</param>
    ''' <param name="obj2">上書きする値を保持するオブジェクトのインスタンス</param>
    ''' <returns>値が上書きされたオブジェクトのインスタンス</returns>
    Public Shared Operator +(ByVal obj1 As BaseObject, ByVal obj2 As BaseObject) As BaseObject
        'FIXME 未実装 Sonodar.Common.BaseObject#+(BaseObject, BaseObject)
        Throw New NotImplementedException()
    End Operator

    ''' <summary>
    ''' obj2のプロパティ値(フィールド値)をobj1のプロパティ値(フィールド値)に上書きした<br/>
    ''' オブジェクトの新規インスタンスを返す。<br/>
    ''' ただし、obj1, obj2のどちらかの値がnullだった場合は、nullとなる。<br/>
    ''' 継承関係がなくても、キー項目が一致していれば比較可能。
    ''' </summary>
    ''' <param name="obj1">値が上書きされるオブジェクトのインスタンス</param>
    ''' <param name="obj2">上書きする値を保持するオブジェクトのインスタンス</param>
    ''' <returns>値が上書きされたオブジェクトのインスタンス</returns>
    Public Shared Operator *(ByVal obj1 As BaseObject, ByVal obj2 As BaseObject) As BaseObject
        'FIXME 未実装 Sonodar.Common.BaseObject#*(BaseObject, BaseObject)
        Throw New NotImplementedException()
    End Operator

    ''' <summary>
    ''' valueとcompareのキー項目(<see cref="Attribute.KeyAttribute">Key属性</see>が付与されたプロパティ(フィールド))を比較し、<br/>
    ''' valueとcompareが一致したらTrueを返す。<br/>
    ''' キー項目が定義されていなければ、すべてのプロパティ(フィールド)を定義順に比較する。<br/>
    ''' 継承関係がなくても、キー項目が一致していれば比較可能。
    ''' </summary>
    ''' <param name="value">値を検証するオブジェクト</param>
    ''' <param name="compare">値を比較するオブジェクト</param>
    ''' <returns>valueとcompareが一致したらTrue</returns>
    Public Shared Operator =(ByVal value As BaseObject, ByVal compare As BaseObject) As Boolean
        If value Is Nothing Then Return (compare Is Nothing)
        Return value.Equals(compare)
    End Operator

    ''' <summary>
    ''' valueとcompareのキー項目(<see cref="Attribute.KeyAttribute">Key属性</see>が付与されたプロパティ(フィールド))を比較し、<br/>
    ''' valueとcompareが一致しなかったらTrueを返す。<br/>
    ''' キー項目が定義されていなければ、すべてのプロパティ(フィールド)を定義順に比較する。<br/>
    ''' 継承関係がなくても、キー項目が一致していれば比較可能。
    ''' </summary>
    ''' <param name="value">値を検証するオブジェクト</param>
    ''' <param name="compare">値を比較するオブジェクト</param>
    ''' <returns>valueとcompareが一致しなかったらTrue</returns>
    Public Shared Operator <>(ByVal value As BaseObject, ByVal compare As BaseObject) As Boolean
        Return Not (value = compare)
    End Operator

    ''' <summary>
    ''' valueとcompareのキー項目(<see cref="Attribute.KeyAttribute">Key属性</see>が付与されたプロパティ(フィールド))を比較し、<br/>
    ''' valueのほうが大きければTrueを返す。<br/>
    ''' キー項目が定義されていなければ、すべてのプロパティ(フィールド)を定義順に比較する。<br/>
    ''' 継承関係がなくても、キー項目が一致していれば比較可能。
    ''' </summary>
    ''' <param name="value">値を検証するオブジェクト</param>
    ''' <param name="compare">値を比較するオブジェクト</param>
    ''' <returns>valueのほうが大きければTrue</returns>
    Public Shared Operator >(ByVal value As BaseObject, ByVal compare As BaseObject) As Boolean
        If value Is Nothing Then Return False
        Return (value.CompareTo(compare) > 0)
    End Operator

    ''' <summary>
    ''' valueとcompareのキー項目(<see cref="Attribute.KeyAttribute">Key属性</see>が付与されたプロパティ(フィールド))を比較し、<br/>
    ''' valueのほうが小さければTrueを返す。<br/>
    ''' キー項目が定義されていなければ、すべてのプロパティ(フィールド)を定義順に比較する。<br/>
    ''' 継承関係がなくても、キー項目が一致していれば比較可能。
    ''' </summary>
    ''' <param name="value">値を検証するオブジェクト</param>
    ''' <param name="compare">値を比較するオブジェクト</param>
    ''' <returns>valueのほうが小さければTrue</returns>
    Public Shared Operator <(ByVal value As BaseObject, ByVal compare As BaseObject) As Boolean
        If value Is Nothing Then Return (compare IsNot Nothing)
        Return (value.CompareTo(compare) < 0)
    End Operator

    ''' <summary>
    ''' valueとcompareのキー項目(<see cref="Attribute.KeyAttribute">Key属性</see>が付与されたプロパティ(フィールド))を比較し、<br/>
    ''' valueがcompare以上であればTrueを返す。<br/>
    ''' キー項目が定義されていなければ、すべてのプロパティ(フィールド)を定義順に比較する。<br/>
    ''' 継承関係がなくても、キー項目が一致していれば比較可能。
    ''' </summary>
    ''' <param name="value">値を検証するオブジェクト</param>
    ''' <param name="compare">値を比較するオブジェクト</param>
    ''' <returns>valueがcompare以上であればTrue</returns>
    Public Shared Operator >=(ByVal value As BaseObject, ByVal compare As BaseObject) As Boolean
        Return Not (value < compare)
    End Operator

    ''' <summary>
    ''' valueとcompareのキー項目(<see cref="Attribute.KeyAttribute">Key属性</see>が付与されたプロパティ(フィールド))を比較し、<br/>
    ''' valueがcompare以下であればTrueを返す。<br/>
    ''' キー項目が定義されていなければ、すべてのプロパティ(フィールド)を定義順に比較する。<br/>
    ''' 継承関係がなくても、キー項目が一致していれば比較可能。
    ''' </summary>
    ''' <param name="value">値を検証するオブジェクト</param>
    ''' <param name="compare">値を比較するオブジェクト</param>
    ''' <returns>valueがcompare以下であればTrue</returns>
    Public Shared Operator <=(ByVal value As BaseObject, ByVal compare As BaseObject) As Boolean
        Return Not (value > compare)
    End Operator

#End Region

#Region "文字列表現メソッド"

    ''' <summary>
    ''' このオブジェクトのJSON表現を取得する。
    ''' </summary>
    ''' <returns>オブジェクトのJSON表現</returns>
    Public Overridable Function ToJsonString() As String
        'FIXME 未実装 Sonodar.Common.BaseObject#ToJsonString()
        Throw New NotImplementedException()
    End Function

    ''' <summary>
    ''' このオブジェクトのXMLを取得する。
    ''' </summary>
    ''' <returns>オブジェクトのXML</returns>
    Public Overridable Function ToXmlString() As String
        'FIXME 未実装 Sonodar.Common.BaseObject#ToXmlString()
        Throw New NotImplementedException()
    End Function

#End Region

    ''' <summary>
    ''' プロパティ値(フィールド値)が同じコピーインスタンスを生成して返す。
    ''' </summary>
    ''' <returns>コピーインスタンス</returns>
    Public Overridable Overloads Function Clone() As Object Implements ICloneable.Clone
        'FIXME 未実装 Sonodar.Common.BaseObject#Clone()
        Throw New NotImplementedException()
    End Function

    ''' <summary>
    ''' プロパティ値(フィールド値)が同じコピーインスタンスを生成して返す。
    ''' </summary>
    ''' <typeparam name="T">コピーするオブジェクトの総称型</typeparam>
    ''' <returns>コピーインスタンス</returns>
    Public Overridable Overloads Function Clone(Of T)() As T
        Return DirectCast(Me.Clone(), T)
    End Function

    ''' <summary>
    ''' このインスタンスのキー項目(<see cref="Attribute.KeyAttribute">Key属性</see>が付与されたプロパティ(フィールド))を参照し、<br/>
    ''' １つでもnullまたは空の値があった場合はTrueを返す。<br/>
    ''' キー項目が定義されていなければ、すべてのプロパティ(フィールド)を参照する。
    ''' </summary>
    ''' <returns>空のオブジェクトだったらTrue</returns>
    Public Overridable Function IsEmpty() As Boolean
        'FIXME 未実装 Sonodar.Common.BaseObject#IsEmpty()
        Throw New NotImplementedException()
    End Function

End Class
